package com.app.jingbaoliandong.myapplication;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RadialGradient;
import android.os.Handler;
import android.os.Vibrator;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.animation.ValueAnimator;
import android.graphics.Region;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class SnakeView extends View {

    private Paint paint = new Paint();
    private List<int[]> snake = new ArrayList<>();
    private Direction direction = Direction.RIGHT;
    private int[] food = new int[2];
    private int gridSize;
    private int gridWidth;
    private int gridHeight;
    private boolean gameStarted = false;
    private int score = 0;
    private Handler handler = new Handler();
    private float joystickRadius;
    private float joystickCenterX;
    private float joystickCenterY;
    private Runnable gameLoop = new Runnable() {
        @Override
        public void run() {
            if (gameStarted) {
                moveSnake();
                checkCollision();
                invalidate();
                handler.postDelayed(this, getSpeedDelay()); // 根据速度等级调整延迟
            }
        }
    };
    private Direction highlightedDirection = null;
    private ValueAnimator joystickAnimator;
    private Vibrator vibrator;
    private List<Path> obstaclePaths = new ArrayList<>();
    private List<Region> obstacleRegions = new ArrayList<>();

    public SnakeView(Context context) {
        super(context);
        init();
        vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
    }

    public SnakeView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
        vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
    }

    private void init() {
        paint.setColor(Color.BLACK);
        paint.setTextSize(50);
        setBackgroundColor(Color.parseColor("#F0F8FF")); // 柔和的背景色
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        gridSize = Math.min(w / 30, h / 40); // 根据屏幕大小调整网格大小
        gridWidth = w / gridSize;
        gridHeight = h / gridSize;

        // 初始化蛇的位置和食物的位置
        snake.clear();
        snake.add(new int[]{gridWidth / 2, gridHeight / 2});
        spawnFood();

        // 增大轮盘尺寸
        joystickRadius = gridSize * 5; // 增大轮盘尺寸
        joystickCenterX = joystickRadius + dpToPx(35); // 距离左边35dp
        joystickCenterY = getHeight() - joystickRadius - dpToPx(35); // 距离底部35dp

        // 初始化障碍物
        spawnObstacles();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawSnake(canvas);
        drawFood(canvas);
        drawObstacles(canvas); // 绘制障碍物
        drawScore(canvas);
        drawJoystick(canvas); // 绘制虚拟轮盘
    }

    private void drawSnake(Canvas canvas) {
        paint.setColor(Color.GREEN);
        for (int[] part : snake) {
            // 使用与食物相同的尺寸绘制蛇的身体
            canvas.drawRoundRect(
                    part[0] * gridSize,
                    part[1] * gridSize,
                    (part[0] + 1) * gridSize,
                    (part[1] + 1) * gridSize,
                    gridSize / 2f, gridSize / 2f, paint // 调整圆角半径
            );
        }
    }

    private void drawFood(Canvas canvas) {
        // 使用与蛇相同的尺寸绘制食物
        paint.setShader(new RadialGradient(
                (food[0] + 0.5f) * gridSize,
                (food[1] + 0.5f) * gridSize,
                gridSize / 2f, // 使用与蛇相同的半径
                Color.RED, Color.YELLOW,
                android.graphics.Shader.TileMode.MIRROR
        ));
        canvas.drawCircle(
                (food[0] + 0.5f) * gridSize,
                (food[1] + 0.5f) * gridSize,
                gridSize / 2f, // 使用与蛇相同的半径
                paint
        );
        paint.setShader(null); // 清除shader
    }

    private void drawObstacles(Canvas canvas) {
        paint.setColor(Color.DKGRAY); // 墙的颜色
        paint.setStyle(Paint.Style.FILL);
        for (Path path : obstaclePaths) {
            canvas.drawPath(path, paint);
        }
    }

    private void drawScore(Canvas canvas) {
        paint.setColor(Color.BLACK);
        canvas.drawText("Score: " + score, getWidth() - 300, 100, paint);
    }

    private void drawJoystick(Canvas canvas) {
        paint.setColor(Color.argb(128, 128, 128, 128)); // 半透明灰色
        canvas.drawCircle(joystickCenterX, joystickCenterY, joystickRadius, paint);

        paint.setStyle(Paint.Style.FILL);

        // 绘制方向箭头
        drawArrow(canvas, joystickCenterX, joystickCenterY - joystickRadius / 2, 0, Direction.UP);
        drawArrow(canvas, joystickCenterX, joystickCenterY + joystickRadius / 2, 180, Direction.DOWN);
        drawArrow(canvas, joystickCenterX - joystickRadius / 2, joystickCenterY, 270, Direction.LEFT);
        drawArrow(canvas, joystickCenterX + joystickRadius / 2, joystickCenterY, 90, Direction.RIGHT);
    }

    private void drawArrow(Canvas canvas, float x, float y, float angle, Direction direction) {
        if (direction == highlightedDirection) {
            paint.setColor(Color.YELLOW); // 高亮颜色
        } else {
            paint.setColor(Color.WHITE);
        }

        Path path = createArrowPath(x, y, angle);
        canvas.drawPath(path, paint);
    }

    private Path createArrowPath(float x, float y, float angle) {
        Path path = new Path();
        float arrowSize = joystickRadius / 4;
        path.moveTo(x, y - arrowSize / 2);
        path.lineTo(x - arrowSize / 2, y + arrowSize / 2);
        path.lineTo(x + arrowSize / 2, y + arrowSize / 2);
        path.close();

        // 旋转箭头
        Matrix matrix = new Matrix();
        matrix.postRotate(angle, x, y);
        path.transform(matrix);

        return path;
    }

    private void moveSnake() {
        int[] head = snake.get(0);
        int[] newHead = new int[2];
        switch (direction) {
            case UP:
                newHead[0] = head[0];
                newHead[1] = head[1] - 1;
                break;
            case DOWN:
                newHead[0] = head[0];
                newHead[1] = head[1] + 1;
                break;
            case LEFT:
                newHead[0] = head[0] - 1;
                newHead[1] = head[1];
                break;
            case RIGHT:
                newHead[0] = head[0] + 1;
                newHead[1] = head[1];
                break;
        }

        // 边界穿越
        if (newHead[0] < 0) newHead[0] = gridWidth - 1;
        if (newHead[0] >= gridWidth) newHead[0] = 0;
        if (newHead[1] < 0) newHead[1] = gridHeight - 1;
        if (newHead[1] >= gridHeight) newHead[1] = 0;

        snake.add(0, newHead);
        if (newHead[0] == food[0] && newHead[1] == food[1]) {
            score++;
            spawnFood();
        } else {
            snake.remove(snake.size() - 1);
        }
    }

    private void spawnFood() {
        Random random = new Random();
        food[0] = random.nextInt(gridWidth);
        food[1] = random.nextInt(gridHeight);

        // 启动食物被吃掉的动画
        startFoodEatenAnimation();

        // 每次吃到食物后刷新障碍物
        spawnObstacles();
    }

    private void startFoodEatenAnimation() {
        ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
        animator.setDuration(500); // 动画持续时间
        animator.addUpdateListener(animation -> {
            float fraction = animation.getAnimatedFraction();
            // 绘制动画效果，例如改变食物的颜色或大小
            paint.setColor(Color.argb((int) (255 * (1 - fraction)), 255, 0, 0)); // 渐变效果
            invalidate();
        });
        animator.start();

        // 震动设备
        if (vibrator != null && vibrator.hasVibrator()) {
            vibrator.vibrate(100); // 震动100毫秒
        }
    }

    private void spawnObstacles() {
        obstaclePaths.clear();
        obstacleRegions.clear();
        Random random = new Random();
        int baseObstacles = 3; // 基础障碍物数量
        int additionalObstacles = score / 5; // 每5分增加一个障碍物
        int numberOfObstacles = baseObstacles + additionalObstacles; // 总障碍物数量

        for (int i = 0; i < numberOfObstacles; i++) {
            Path path = new Path();
            int startX = random.nextInt(gridWidth - 2) * gridSize; // 确保墙不会超出边界
            int startY = random.nextInt(gridHeight - 2) * gridSize;
            int wallLength = random.nextInt(3) + 2; // 墙的长度为2到4个格子

            // 随机选择水平或垂直墙
            if (random.nextBoolean()) {
                // 水平墙
                path.addRect(startX, startY, startX + wallLength * gridSize, startY + gridSize, Path.Direction.CW);
            } else {
                // 垂直墙
                path.addRect(startX, startY, startX + gridSize, startY + wallLength * gridSize, Path.Direction.CW);
            }

            obstaclePaths.add(path);

            // 创建一个区域来检测碰撞
            Region region = new Region();
            region.setPath(path, new Region(0, 0, gridWidth * gridSize, gridHeight * gridSize));
            obstacleRegions.add(region);
        }
    }

    private void checkCollision() {
        int[] head = snake.get(0);
        for (int i = 1; i < snake.size(); i++) {
            if (head[0] == snake.get(i)[0] && head[1] == snake.get(i)[1]) {
                resetGame();
                return; // 确保在检测到碰撞后立即退出循环
            }
        }
        // 检查与障碍物的碰撞
        for (Region region : obstacleRegions) {
            if (region.contains(head[0] * gridSize, head[1] * gridSize)) {
                resetGame();
                return;
            }
        }
    }

    private void resetGame() {
        snake.clear();
        snake.add(new int[]{gridWidth / 2, gridHeight / 2});
        direction = Direction.RIGHT;
        score = 0;
        spawnFood();
        gameStarted = false;
        handler.removeCallbacks(gameLoop); // 确保停止当前的游戏循环
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (!gameStarted) {
                    gameStarted = true;
                    handler.post(gameLoop);
                }
                if (x < getWidth() / 2) {
                    startJoystickAnimation(x, y);
                }
                break;

            case MotionEvent.ACTION_MOVE:
                if (Math.pow(x - joystickCenterX, 2) + Math.pow(y - joystickCenterY, 2) <= Math.pow(joystickRadius, 2)) {
                    float dx = x - joystickCenterX;
                    float dy = y - joystickCenterY;

                    Direction newDirection = null;
                    if (Math.abs(dx) > Math.abs(dy)) {
                        if (dx > 0 && direction != Direction.LEFT) {
                            newDirection = Direction.RIGHT;
                        } else if (dx < 0 && direction != Direction.RIGHT) {
                            newDirection = Direction.LEFT;
                        }
                    } else {
                        if (dy > 0 && direction != Direction.UP) {
                            newDirection = Direction.DOWN;
                        } else if (dy < 0 && direction != Direction.DOWN) {
                            newDirection = Direction.UP;
                        }
                    }

                    if (newDirection != null && newDirection != direction) {
                        direction = newDirection;
                        highlightedDirection = newDirection;
                        invalidate(); // 触发重绘以显示高亮
                    }
                }
                break;

            case MotionEvent.ACTION_UP:
                highlightedDirection = null;
                invalidate(); // 触发重绘以移除高亮
                break;
        }
        return true;
    }

    private void startJoystickAnimation(float targetX, float targetY) {
        if (joystickAnimator != null && joystickAnimator.isRunning()) {
            joystickAnimator.cancel();
        }

        final float startX = joystickCenterX;
        final float startY = joystickCenterY;

        joystickAnimator = ValueAnimator.ofFloat(0, 1);
        joystickAnimator.setDuration(300); // 动画持续时间
        joystickAnimator.addUpdateListener(animation -> {
            float fraction = animation.getAnimatedFraction();
            joystickCenterX = startX + (targetX - startX) * fraction;
            joystickCenterY = startY + (targetY - startY) * fraction;
            invalidate();
        });
        joystickAnimator.start();
    }

    private float dpToPx(float dp) {
        return dp * getResources().getDisplayMetrics().density;
    }

    private int getSpeedDelay() {
        // 根据得分计算速度等级
        int level = Math.min(score / 5, 4); // 每吃5个食物增加一级，最高5级
        int[] speedDelays = {150, 120, 90, 60, 30}; // 调整初始延迟时间
        return speedDelays[level];
    }

    private enum Direction {
        UP, DOWN, LEFT, RIGHT
    }
} 